using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
using System.Reflection;
using System.Collections.ObjectModel;

namespace PeopleEditor.Features.Feature1
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("4ae3953e-636c-45aa-98eb-d84d6d48ca47")]
    public class Feature1EventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            //SPWebApplication webApp = SPContext.Current.Site.WebApplication;//(SPWebApplication)properties.Feature.Parent;
            //SPSite spsite = ((SPWeb)properties.Feature.Parent).Site;
            SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent;  //spsite.WebApplication;
            //SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent;
            deployPeoplePicker(webApp, properties.Feature.DefinitionId.ToString());
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            //SPWebApplication webApp = SPContext.Current.Site.WebApplication; //(SPWebApplication)properties.Feature.Parent;
            //SPSite webApp = (SPSite)properties.Feature.Parent;
            //SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent;
            //SPSite spsite = ((SPWeb)properties.Feature.Parent).Site;
            SPWebApplication webApp = (SPWebApplication)properties.Feature.Parent;
            retractPeoplePicker(webApp, properties.Feature.DefinitionId.ToString());
        }


        // Uncomment the method below to handle the event raised after a feature has been installed.

        //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        //{
        //}


        // Uncomment the method below to handle the event raised before a feature is uninstalled.

        //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised when a feature is upgrading.

        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}
        
        #region Private methods
        /// <summary>
        /// Deploy the PeoplePicker web.config modifications
        /// </summary>
        /// <param name="webApp"></param>
        private void deployPeoplePicker(SPWebApplication webApp, string ownerID)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                webApp.Sites[0].AllowUnsafeUpdates = true;
                //Add Assembly
                //string modificationName = string.Format(@"add[@assembly='{0}']", Assembly.GetExecutingAssembly().FullName);
                //SPWebConfigModification modification = new SPWebConfigModification(modificationName, "configuration/system.web/compilation/assemblies");
                //modification.Path = "configuration/system.web/compilation/assemblies";
                //modification.Value = string.Format(@"<add assembly=""{0}"" />", Assembly.GetExecutingAssembly().FullName);
                //modification.Owner = ownerID;
                //modification.Sequence = 0;
                //modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
                //webApp.WebConfigModifications.Add(modification);



                //Add tagMapping
                string modificationName = string.Format(@"add[@tagType='Microsoft.SharePoint.WebControls.PeopleEditor'][@mappedTagType='PeopleEditor.CustPeopleFind,{0}']", 
                    Assembly.GetExecutingAssembly().FullName);
                SPWebConfigModification modification = new SPWebConfigModification //(modificationName, "configuration/system.web/pages/tagMapping");
                {
                    Path = "configuration/system.web/pages/tagMapping",
                    Name = modificationName,
                    Value = string.Format(@"<add tagType=""Microsoft.SharePoint.WebControls.PeopleEditor"" mappedTagType=""PeopleEditor.CustPeopleFind"" />"),
                    Owner = ownerID,
                    Sequence = 1,
                    Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode                    
                };
                webApp.WebConfigModifications.Add(modification);

                //Save changes
                webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

                //Serialize and propagate changes across farm
                webApp.Update();

                //Create the persistent objects
                Common.CreatePersistentObjects(webApp);
            });            
        }

        /// <summary>
        /// Retract the PeoplePicker web.config modifications
        /// </summary>
        /// <param name="webApp"></param>
        private void retractPeoplePicker(SPWebApplication webApp, string ownerID)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                Collection<SPWebConfigModification> modifications = webApp.WebConfigModifications;
                int originalNumberOfModifications = modifications.Count;

                //removing items from the collection will decrease its count so loop with i--
                for (int i = originalNumberOfModifications - 1; i >= 0; i--)
                {
                    SPWebConfigModification modification = modifications[i];
                    if (modification.Owner == ownerID)
                    {
                        modifications.Remove(modification);
                    }
                }

                //Save changes when necessary
                if (originalNumberOfModifications > modifications.Count)
                {
                    webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
                    webApp.Update();
                }

                //Delete the persistent objects
                PeoplePickerSettings commonSettings = webApp.GetChild<PeoplePickerSettings>(Globals.CommonSettingsName);
                if (commonSettings != null)
                {
                    //Restore initial values for web application PeoplePicker settings
                    SPPeoplePickerSettings webAppPeopleSettings = webApp.PeoplePickerSettings;
                    webAppPeopleSettings.OnlySearchWithinSiteCollection = commonSettings.OnlySearchWithinSiteCollection;

                    //Delete the persistent object
                    commonSettings.Delete();
                    commonSettings.Unprovision();
                }
                PeoplePickerSettings adminSettings = webApp.GetChild<PeoplePickerSettings>(Globals.AdminSettingsName);
                if (adminSettings != null)
                {
                    adminSettings.Delete();
                    adminSettings.Unprovision();
                }

                //Serialize and propagate changes across farm
                webApp.Update();
            });
        }
        #endregion
    }
}
